package com.yupi.yuoj.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.yuoj.annotation.AuthCheck;
import com.yupi.yuoj.common.BaseResponse;
import com.yupi.yuoj.common.DeleteRequest;
import com.yupi.yuoj.common.ErrorCode;
import com.yupi.yuoj.common.ResultUtils;
import com.yupi.yuoj.constant.UserConstant;
import com.yupi.yuoj.exception.BusinessException;
import com.yupi.yuoj.exception.ThrowUtils;
import com.yupi.yuoj.model.dto.articles.ArticleWriteRequest;
import com.yupi.yuoj.model.entity.Articles;
import com.yupi.yuoj.model.entity.ArticleTags;
import com.yupi.yuoj.model.entity.User;
import com.yupi.yuoj.model.vo.ArticleVO;
import com.yupi.yuoj.service.ArticlesService;
import com.yupi.yuoj.service.ArticleTagsService;
import com.yupi.yuoj.service.UserService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

/**
 * 文章接口
 *
 * @author yupi
 */
@RestController
@RequestMapping("/articles")
@Slf4j
public class ArticlesController {

    @Resource
    private ArticlesService articlesService;

    @Resource
    private UserService userService;

    @Resource
    private ArticleTagsService articleTagsService;

    // region 增删改查

    /**
     * 创建文章
     *
     * @param articles
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addArticle(@RequestBody Articles articles, HttpServletRequest request) {
        if (articles == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        articles.setUser_id(loginUser.getId());
        articles.setView_count(0L);
        articles.setLike_count(0);
        articles.setComment_count(0);
        articles.setCollect_count(0);
        articles.setShare_count(0);
        boolean result = articlesService.save(articles);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        long newArticleId = articles.getId();
        return ResultUtils.success(newArticleId);
    }

    /**
     * 写文章（简化版）
     *
     * @param writeRequest
     * @param request
     * @return
     */
    @PostMapping("/write")
    public BaseResponse<Long> writeArticle(@RequestBody ArticleWriteRequest writeRequest, HttpServletRequest request) {
        if (writeRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        // 校验必填字段
        String title = writeRequest.getTitle();
        String content = writeRequest.getContent();
        if (title == null || title.trim().isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文章标题不能为空");
        }
        if (content == null || content.trim().isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文章内容不能为空");
        }
        
        User loginUser = userService.getLoginUser(request);
        
        // 创建文章实体
        Articles article = new Articles();
        article.setUser_id(loginUser.getId());
        article.setTitle(title.trim());
        article.setContent(content);
        article.setCategory_id(writeRequest.getCategoryId());
        
        // 设置可选字段
        if (writeRequest.getSummary() != null && !writeRequest.getSummary().trim().isEmpty()) {
            article.setSummary(writeRequest.getSummary().trim());
        }
        if (writeRequest.getCoverImage() != null && !writeRequest.getCoverImage().trim().isEmpty()) {
            article.setCover_image(writeRequest.getCoverImage().trim());
        }
        
        // 设置默认值
        article.setView_count(0L);
        article.setLike_count(0);
        article.setComment_count(0);
        article.setCollect_count(0);
        article.setShare_count(0);
        article.setWord_count(content.length()); // 简单计算字数
        article.setReading_time((int) Math.ceil(content.length() / 300.0)); // 按300字/分钟估算阅读时间
        article.setStatus(1); // 1已发布
        article.setIs_original(writeRequest.getIsOriginal() != null ? (writeRequest.getIsOriginal() ? 1 : 0) : 1); // 默认原创
        article.setIs_top(0); // 默认不置顶
        article.setIs_featured(0); // 默认不精选
        article.setAllow_comment(writeRequest.getAllowComment() != null ? (writeRequest.getAllowComment() ? 1 : 0) : 1); // 默认允许评论
        article.setContent_type(1); // 默认markdown
        
        // 生成slug（简单处理）
        String slug = title.trim().toLowerCase()
                .replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5\\s]", "")
                .replaceAll("\\s+", "-");
        if (slug.length() > 50) {
            slug = slug.substring(0, 50);
        }
        article.setSlug(slug + "-" + System.currentTimeMillis());
        
        // 保存文章
        boolean result = articlesService.save(article);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        
        long newArticleId = article.getId();
        
        // 处理标签关联
        if (writeRequest.getTagIds() != null && !writeRequest.getTagIds().isEmpty()) {
            for (Integer tagId : writeRequest.getTagIds()) {
                if (tagId != null && tagId > 0) {
                    ArticleTags articleTag = new ArticleTags();
                    articleTag.setArticle_id(newArticleId);
                    articleTag.setTag_id(tagId);
                    articleTagsService.save(articleTag);
                }
            }
        }
        
        return ResultUtils.success(newArticleId);
    }

    /**
     * 删除文章
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteArticle(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getLoginUser(request);
        long id = deleteRequest.getId();
        // 判断是否存在
        Articles oldArticle = articlesService.getById(id);
        ThrowUtils.throwIf(oldArticle == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可删除
        if (!oldArticle.getUser_id().equals(user.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean b = articlesService.removeById(id);
        return ResultUtils.success(b);
    }

    /**
     * 更新文章（仅管理员）
     *
     * @param articles
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateArticle(@RequestBody Articles articles) {
        if (articles == null || articles.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Articles oldArticle = articlesService.getById(articles.getId());
        ThrowUtils.throwIf(oldArticle == null, ErrorCode.NOT_FOUND_ERROR);
        boolean result = articlesService.updateById(articles);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取文章
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<Articles> getArticleById(@RequestParam Long id, HttpServletRequest request) {
        if (id == null || id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Articles article = articlesService.getById(id);
        if (article == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        return ResultUtils.success(article);
    }

    /**
     * 分页获取文章列表（仅管理员）
     *
     * @param current
     * @param size
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<ArticleVO>> listArticleByPage(@RequestParam long current, @RequestParam long size) {
        Page<ArticleVO> articleVOPage = articlesService.getArticleVOPage(current, size);
        return ResultUtils.success(articleVOPage);
    }

    /**
     * 公开获取文章列表
     *
     * @param current
     * @param size
     * @param categoryId
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<ArticleVO>> listPublicArticles(
            @RequestParam(defaultValue = "1") long current,
            @RequestParam(defaultValue = "10") long size,
            @RequestParam(required = false) Long categoryId) {
        if (current <= 0 || size <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        // 调用service层方法获取ArticleVO分页数据
        Page<ArticleVO> articleVOPage = articlesService.getArticleVOPage(current, size, categoryId);
        
        return ResultUtils.success(articleVOPage);
    }

    /**
     * 分页获取当前用户创建的文章列表
     *
     * @param current
     * @param size
     * @param request
     * @return
     */
    @PostMapping("/my/list/page")
    public BaseResponse<Page<Articles>> listMyArticleByPage(@RequestParam long current, @RequestParam long size,
            HttpServletRequest request) {
        if (current <= 0 || size <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Page<Articles> articlePage = articlesService.lambdaQuery()
                .eq(Articles::getUser_id, loginUser.getId())
                .page(new Page<>(current, size));
        return ResultUtils.success(articlePage);
    }

    /**
     * 编辑文章（用户）
     *
     * @param articles
     * @param request
     * @return
     */
    @PostMapping("/edit")
    public BaseResponse<Boolean> editArticle(@RequestBody Articles articles, HttpServletRequest request) {
        if (articles == null || articles.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Articles oldArticle = articlesService.getById(articles.getId());
        ThrowUtils.throwIf(oldArticle == null, ErrorCode.NOT_FOUND_ERROR);
        User loginUser = userService.getLoginUser(request);
        // 仅本人或管理员可编辑
        if (!oldArticle.getUser_id().equals(loginUser.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean result = articlesService.updateById(articles);
        return ResultUtils.success(result);
    }

}